<template>
  <div class="cascader-menu">
    <div class="cascader-menu__header">
      <div class="title">{{ title }}</div>
      <div class="header-operate">
        <a-input-search
          placeholder="关键词搜索"
          class="header-search-input"
          @search="onSearch"
        />
        <a-icon type="close" @click="$emit('close')" />
      </div>
    </div>
    <div
      v-if="showOptions && showOptions.length"
      key="data-body"
      class="cascader-menu__body"
      :style="
        `width: ${width ? width + 'px' : 'auto'}; height: ${
          height ? height + 'px' : 'auto'
        }`
      "
    >
      <IndexColumn
        v-if="indexed"
        class="cascader-menu__body__index"
        :cascader-name="cascaderName"
        :container-node="anchorContainerNode"
        :options="indexlist"
      />
      <CascaderColumn
        v-for="(list, listIndex) in showOptions"
        :key="`cascader-column-${listIndex}`"
        :values="values"
        :options="list"
        :level="listIndex"
        :height="height"
        :indexed="indexed && listIndex === 0"
        :cascader-name="cascaderName"
        :class="
          listIndex === headers.length - 1
            ? 'flex-auto'
            : 'cascader-menu__body__column'
        "
        @node="getNode"
        @change="(option, checked) => handleSelect(option, checked, listIndex)"
      />
      <div
        v-if="headers && showOptions.length !== headers.length"
        class="costum-content"
      >
        {{
          `点击${headers[showOptions.length - 1]}可进行${
            headers[showOptions.length]
          }选择`
        }}
      </div>
    </div>
    <div
      v-if="!showOptions || !showOptions.length"
      key="empty-body"
      class="cascader-menu__empty"
      :style="
        `width: ${width ? width + 'px' : 'auto'}; height: ${
          height ? height + 'px' : 'auto'
        }`
      "
    >
      <IwEmpty class="empty" desc="赞无数据" />
    </div>
    <div class="cascader-menu__footer">
      <div class="selected-text">
        {{ selectText }}
      </div>
      <div>
        <a-button @click="handleReset">清空</a-button>
        <a-button type="primary" @click="handleConfirm">
          确定
        </a-button>
      </div>
    </div>
  </div>
</template>

<script>
import _ from "lodash";
import IndexColumn from "./IndexColumn.vue";
import CascaderColumn from "./CascaderColumn.vue";
import IwEmpty from "@/components/IwEmpty/index.vue";
import {
  getLevelOptions,
  flattenOptions,
  setSelected,
  setParentIndet,
  getValues,
  setParentFiltered,
  getFilteredOptions,
  setFiltered,
  getSelectOptions
} from "@/utils/helper";

export default {
  components: {
    IndexColumn,
    CascaderColumn,
    IwEmpty
  },
  props: {
    options: {
      type: Array,
      default: () => []
    },
    value: {
      type: Array,
      default: () => []
    },
    title: {
      type: String,
      default: ""
    },
    height: {
      type: Number,
      default: 0
    },
    indexed: {
      type: Boolean,
      default: false
    },
    visibled: {
      type: Boolean,
      default: false
    },
    headers: {
      type: Array,
      default: () => []
    },
    cascaderName: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      showOptions: [],
      indexlist: [],
      maxLevel: 0,
      anchorContainerNode: null,
      width: 540,
      values: [],
      selectOptions: [],
      keyword: "",
      selectedList: []
    };
  },
  computed: {
    selectText() {
      if (this.selectedList.length) {
        const length = this.selectedList.length;
        const list = this.selectedList[length - 1];
        return list.length && list.length
          ? `已选${list.length}个${this.headers[length - 1]}`
          : "默认选择全部";
      }
      return "默认选择全部";
    }
  },
  watch: {
    options(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.getIndexList();
        this.init(this.value);
      }
    },
    value(newVal, oldVal) {
      if (newVal !== oldVal) {
        this.getIndexList();
        this.init(this.value);
      }
    },
    visibled(val) {
      if (!val) {
        this.init(this.value);
      }
    }
  },
  mounted() {
    // 计算最深的层级
    this.maxLevel = this.headers.length - 1;
    // 计算弹出框宽度
    this.width = 189 * (this.headers.length + 1);
    this.getIndexList();
    this.init(this.value);
  },
  methods: {
    init(values) {
      // 初始化选中项的key
      this.values = [...values];
      this.getInitOptions();
      this.keyword = "";
    },
    // 获取展示数据源
    getShowOptions(options) {
      // 初始化展示数据源
      this.showOptions = options
        .filter((item, index) => index <= this.maxLevel)
        .map((item, index) => {
          if (index === 0) {
            let data = [];
            data = this.options;
            return flattenOptions(data, index);
          }
          return flattenOptions(item, index);
        })
        .filter(item => item.length);
      // console.log(1111111111, this.showOptions, new Date().getTime() - start);
    },
    // 获取索引列表
    getIndexList() {
      if (this.indexed) {
        this.indexlist =
          this.options && this.options.length
            ? this.options.map(item => item.key)
            : [];
      }
    },
    // 获取索引容器节点
    getNode(node) {
      this.anchorContainerNode = node;
    },
    // 搜索
    onSearch(text) {
      // if (!text) return;
      this.keyword = text;
      this.getSearchOptions();
    },
    // 更新展示数据源数据源
    getInitOptions() {
      const options = getLevelOptions(this.options, this.maxLevel);

      this.selectedList = getSelectOptions(this.options).filter(
        item => item.length
      );
      this.getShowOptions(options);
    },
    getSearchOptions() {
      // 清空过滤状态
      setFiltered(this.options);
      this.getInitOptions();
      if (!this.keyword) return;
      const length = this.showOptions.length;
      // 修改展示数据源最后一层的过滤状态
      this.showOptions[length - 1].forEach(item => {
        if (item.isTitle !== length - 1 && item.value.includes(this.keyword)) {
          item.filtered = true;
        }
      });
      // 修改父级过滤状态
      // if (length > 1) {
      setParentFiltered(this, this.options, this.keyword);
      // }
      // 通过过滤状态获取层数数据源
      const options = getFilteredOptions(this.options, this.maxLevel);
      // 计算出新的展示数据源
      this.showOptions = options
        .filter((item, index) => index <= this.maxLevel)
        .map((item, index) => flattenOptions(item, index, true))
        .filter(item => item.length);
    },
    // 选中某项
    handleSelect(option, checked, level) {
      this.getSelectValues(option, checked, level);
    },
    // 根据选中项目获取选中key集合
    getSelectValues(option, checked) {
      let values = [];
      // 取消选中时需要将该项及他的所有后代项的key全部去除
      if (!checked && option.children && option.children.length) {
        values = getValues(option.children);
      }
      values.push(option.key);

      const lastValues = checked
        ? [option.key, ...this.values]
        : this.values.filter(item => !values.includes(item));

      this.values = _.uniq(lastValues);

      const selectedSet = new Set(this.values);
      // 设置子级选中状态
      if (option.children && option.children.length) {
        setSelected(this, option.children, selectedSet);
      }

      // 设置父级选中状态
      setParentIndet(this, this.options, selectedSet);

      if (this.keyword) {
        // 获取查询展示数据源
        this.getSearchOptions();
      } else {
        this.getInitOptions();
      }
    },
    // 清空
    handleReset() {
      this.values = [];
      this.$emit("reset");
      this.init([]);
    },
    // 确定
    handleConfirm() {
      const levelValues = this.selectedList.length
        ? this.selectedList.map(item => item.map(sub => sub.key))
        : [];
      debugger
      this.$emit("confirm", this.values, this.selectedList, levelValues);
    }
  }
};
</script>

<style lang="less" scoped>
@C: cascader-menu;
.@{C} {
  position: relative;

  &__header {
    padding: 10px 15px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #ecedf2;

    .title {
      font-family: PingFangSC-Semibold;
      font-size: 18px;
      color: #292b33;
      line-height: 18px;
      font-weight: 600;
    }

    .header-operate {
      display: flex;
      align-items: center;

      i {
        margin-left: 20px;
        font-size: 16px;
        cursor: pointer;
      }
    }

    .header-search-input {
      width: 170px;
      /deep/ .ant-input {
        font-size: 12px;
      }
    }
  }
  &__body {
    display: flex;
    align-items: flex-start;

    &__index {
      flex: 0 0 auto;
    }

    &__column {
      width: 189px;
      max-width: 189px;
      flex: 0 0 auto;
      border-right: 1px solid #ecedf2;
    }
    .flex-auto {
      flex: 1;
      overflow-x: hidden;
    }

    .costum-content {
      height: 100%;
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }

  &__empty {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  &__footer {
    padding: 10px 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-top: 1px solid #ecedf2;

    .selected-text {
      color: #4f6ef2;
      // cursor: pointer;
    }
  }
  .selected-list {
    position: absolute;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    background-color: #fff;
    border: 1px solid #ecedf2;
    box-shadow: 0 16px 47px 0 rgba(25, 41, 115, 0.04);
  }
}
</style>
